use std::fs;
use std::path::Path;
use std::io::{Result, Read};
use mlua::Lua;
use crate::util::util::*;
use std::sync::Arc;
use std::sync::atomic::AtomicU32;

pub struct MyLuaManage {
    // pub lua:Arc<Mutex<Lua>>,
    register_handle: Vec<Box<dyn Fn(&Lua) + Send + Sync + 'static>>,
    max:u32,
    max_index:Arc<AtomicU32>,
    script:&'static str
}

impl MyLuaManage {
    //构建
    pub fn build(max:u32)->Self{
        let max_index = Arc::new(AtomicU32::new(0));
        let register_handle = vec![];
        MyLuaManage{ register_handle,max,max_index ,script:""}
    }
    //注册module方法
    pub fn register<F>(&mut self,f:F)
        where F:Fn(&Lua) + Send + Sync + 'static
    {
        self.register_handle.push(Box::new(f))
    }
    //加载脚本文件
    pub fn load_from_file<T:AsRef<Path>>(&mut self,p:T) ->Result<()>{
        let mut file = fs::OpenOptions::new()
            .read(true)
            .open(p)?;
        let mut buf = Vec::new();
        let _ = file.read_to_end(&mut buf)?;
        self.script = buf.as_str();
        Ok(())
    }
    //生成lua
    pub fn generate(&self)->&'static Lua{
        let lua = Lua::new().into_static();
        for handler in self.register_handle.iter() {
            handler(lua);
        }
        lua
    }
    //销毁lua
    pub fn destroy(lua:&'static Lua){
        unsafe { Lua::from_static(lua) };
    }

    pub fn get_max(&self)->u32{
        self.max
    }
    pub fn get_index(&self)->Arc<AtomicU32>{
        self.max_index.clone()
    }
    pub fn get_script(&self)->&'static str{
        self.script
    }
}